home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / editors / dme1314.of6 < prev    next >
Text File  |  1988-10-22  |  49KB  |  2,152 lines

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!uflorida!gatech!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i012:  dme - programmer's text editor V1.31, Part04/06
  5. Message-ID: <9774@swan.ulowell.edu>
  6. Date: 22 Oct 88 04:33:17 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2141
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 12
  13. Archive-name: editors/dme131.4of6
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    ./src/menu.c
  20. #    ./src/mods.c
  21. #    ./src/rexxbind.asm
  22. #    ./src/command.c
  23. #    ./src/cmd3.c
  24. #    ./src/keyboard.c
  25. #
  26. if `test ! -d ./src`
  27. then
  28.   mkdir ./src
  29.   echo "mkdir ./src"
  30. fi
  31. if `test ! -s ./src/menu.c`
  32. then
  33. echo "writing ./src/menu.c"
  34. cat > ./src/menu.c << '\Rogue\Monster\'
  35.  
  36. /*
  37.  *  MENU.C
  38.  *
  39.  *  Menu routines... made to take up as little space as possible, and
  40.  *  thus uses many tricks which you should watch out for.
  41.  */
  42.  
  43. #include "defs.h"
  44.  
  45. typedef struct {
  46.     ITEM item;
  47.     char *com;
  48. } XITEM;
  49.  
  50. short Menuoff;
  51. short DoMenuoff;
  52.  
  53. MENU *Menu;
  54.  
  55. menu_strip(win)
  56. WIN *win;
  57. {
  58.     if (!Menuoff && Menu) {
  59.     SetMenuStrip(win,Menu);
  60.     Forbid();
  61.     win->Flags &= ~RMBTRAP;
  62.     Permit();
  63.     }
  64. }
  65.  
  66. menu_off()
  67. {
  68.     register ED *ed;
  69.     if (Menuoff == 0) {
  70.     for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) {
  71.         ClearMenuStrip(ed->Win);
  72.         Forbid();
  73.         ed->Win->Flags |= RMBTRAP;
  74.         Permit();
  75.     }
  76.     }
  77.     ++Menuoff;
  78. }
  79.  
  80. menu_on()
  81. {
  82.     register ED *ed;
  83.     if (Menu && Menuoff == 1) {
  84.     fixmenu();
  85.     for (ed = (ED *)DBase.mlh_Head; ed->Node.mln_Succ; ed = (ED *)ed->Node.mln_Succ) {
  86.         SetMenuStrip(ed->Win,Menu);
  87.         Forbid();
  88.         ed->Win->Flags &= ~RMBTRAP;
  89.         Permit();
  90.     }
  91.     }
  92.     --Menuoff;
  93. }
  94.  
  95. do_menuoff()
  96. {
  97.     menu_off();
  98.     ++DoMenuoff;
  99. }
  100.  
  101. do_menuon()
  102. {
  103.     if (DoMenuoff) {
  104.     --DoMenuoff;
  105.     menu_on();
  106.     }
  107. }
  108.  
  109. char *
  110. menutomacro(str)
  111. char *str;
  112. {
  113.     char header[64];
  114.     char itembuf[64];
  115.     register short i;
  116.     register char *ptr;
  117.     register MENU *menu;
  118.     register ITEM *item;
  119.  
  120.     for (i = 0; str[i] && str[i] != '-'; ++i);
  121.     if (str[i] == '-') {
  122.     strncpy(header, str, i);
  123.     header[i] = 0;
  124.     strcpy(itembuf, str + i + 1);
  125.     for (menu = Menu; menu; menu = menu->NextMenu) {
  126.         if (ncstrcmp(header, menu->MenuName) == 0) {
  127.         for (item = menu->FirstItem; item; item = item->NextItem) {
  128.             ptr = (char *)((ITEXT *)item->ItemFill)->IText;
  129.             if (ncstrcmp(itembuf, ptr) == 0) {
  130.             ptr = ((XITEM *)item)->com;
  131.             goto done;
  132.             }
  133.         }
  134.         }
  135.     }
  136.     }
  137.     ptr = NULL;
  138. done:
  139.     return(ptr);
  140. }
  141.  
  142. char *
  143. menu_cmd(im)
  144. IMESS *im;
  145. {
  146.     XITEM *item;
  147.     char *ptr;
  148.  
  149.     if (item = (XITEM *)ItemAddress(Menu, im->Code))
  150.     return(item->com);
  151.     return(NULL);
  152. }
  153.  
  154. fixmenu()
  155. {
  156.     register MENU *menu;
  157.     register ITEM *item;
  158.     register ITEXT *it;
  159.     register int row, col, maxc, scr;
  160.  
  161.     col = 0;
  162.     for (menu = Menu; menu; menu = menu->NextMenu) {
  163.     maxc = strlen(menu->MenuName);
  164.     row = 0;
  165.     for (item = menu->FirstItem; item; item = item->NextItem) {
  166.         it = (ITEXT *)item->ItemFill;
  167.         item->TopEdge = row;
  168.         scr = strlen(((ITEXT *)item->ItemFill)->IText);
  169.         if (scr > maxc)
  170.         maxc = scr;
  171.         item->Height = 10;
  172.         row += item->Height;
  173.     }
  174.     maxc = (maxc * 8) + 16;
  175.     for (item = menu->FirstItem; item; item = item->NextItem)
  176.         item->Width = maxc;
  177.     menu->Width = maxc;
  178.     menu->LeftEdge = col;
  179.     menu->Height = row;
  180.     col += maxc;
  181.     }
  182. }
  183.  
  184. /*
  185.  *  menuclear
  186.  *  menuadd    header    item    command
  187.  *  menudel    header    item
  188.  *  menudelhdr    header
  189.  */
  190.  
  191. do_menuclear()
  192. {
  193.     menu_off();
  194.     while (Menu) {
  195.     av[1] = (ubyte *)Menu->MenuName;
  196.     do_menudelhdr();
  197.     }
  198.     menu_on();
  199. }
  200.  
  201. do_menuadd()
  202. {
  203.     register MENU *menu, **mpr;
  204.     register ITEM *item, **ipr;
  205.     register ITEXT *it;
  206.  
  207.     menu_off();
  208.     mpr = &Menu;
  209.     for (menu = *mpr; menu; menu = *mpr) {
  210.     if (strcmp(av[1], menu->MenuName) == 0) {
  211.         ipr = &menu->FirstItem;
  212.         for (item = *ipr; item; item = *ipr) {
  213.         if (strcmp(av[2], ((ITEXT *)item->ItemFill)->IText) == 0)
  214.             goto newname;
  215.         ipr = &item->NextItem;
  216.         }
  217.         goto newitem;
  218.     }
  219.     mpr = &menu->NextMenu;
  220.     }
  221. newmenu:    /*    create new menu */
  222.     menu = malloc(sizeof(MENU));
  223.     bzero(menu, sizeof(MENU));
  224.     menu->NextMenu = *mpr;
  225.     *mpr = menu;
  226.     menu->Flags = MENUENABLED;
  227.     menu->MenuName = malloc(strlen(av[1])+1);
  228.     strcpy(menu->MenuName, av[1]);
  229.     ipr = &menu->FirstItem;
  230.     *ipr = NULL;
  231. newitem:    /*    create new item */
  232.     it = malloc(sizeof(ITEXT));
  233.     bzero(it, sizeof(ITEXT));
  234.     it->BackPen = 1;
  235.     it->DrawMode = JAM2;
  236.     it->IText = malloc(strlen(av[2])+1);
  237.     strcpy(it->IText, av[2]);
  238.     item = malloc(sizeof(XITEM));
  239.     bzero(item, sizeof(XITEM));
  240.     item->NextItem = *ipr;
  241.     *ipr = item;
  242.     item->ItemFill = (APTR)it;
  243.     item->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP;
  244. newname:    /*    create new name */
  245.     if (((XITEM *)item)->com)
  246.     free(((XITEM *)item)->com);
  247.     ((XITEM *)item)->com = malloc(strlen(av[3])+1);
  248.     strcpy(((XITEM *)item)->com, av[3]);
  249.     menu_on();
  250. }
  251.  
  252. do_menudelhdr()
  253. {
  254.     register MENU *menu;
  255.     register MENU **mpr;
  256.  
  257.     menu_off();
  258.     mpr = &Menu;
  259.     for (menu = *mpr; menu; menu = *mpr) {
  260.     if (strcmp(av[1], menu->MenuName) == 0) {
  261.         if (menu->FirstItem) {
  262.         while (menu->FirstItem) {
  263.             av[2] = ((ITEXT *)menu->FirstItem->ItemFill)->IText;
  264.             if (do_menudel())
  265.             break;
  266.         }
  267.         break;
  268.         }
  269.         *mpr = menu->NextMenu;
  270.         free(menu->MenuName);
  271.         free(menu);
  272.         break;
  273.     }
  274.     mpr = &menu->NextMenu;
  275.     }
  276.     menu_on();
  277. }
  278.  
  279. do_menudel()
  280. {
  281.     register MENU *menu;
  282.     register ITEM *item, **ipr;
  283.     register ITEXT *it;
  284.     short ret = 0;
  285.  
  286.     menu_off();
  287.     for (menu = Menu; menu; menu = menu->NextMenu) {
  288.     if (strcmp(av[1], menu->MenuName) == 0) {
  289.         ipr = &menu->FirstItem;
  290.         for (item = *ipr; item; item = *ipr) {
  291.         it = (ITEXT *)item->ItemFill;
  292.         if (strcmp(av[2], it->IText) == 0) {
  293.             *ipr = item->NextItem;
  294.             free(it->IText);
  295.             free(it);
  296.             free(((XITEM *)item)->com);
  297.             free(item);
  298.             if (!menu->FirstItem) {
  299.             do_menudelhdr();
  300.             ret = 1;
  301.             }
  302.             menu_on();
  303.             return(ret);
  304.         }
  305.         ipr = &item->NextItem;
  306.         }
  307.     }
  308.     }
  309.     menu_on();
  310.     return(ret);
  311. }
  312.  
  313. \Rogue\Monster\
  314. else
  315.   echo "will not over write ./src/menu.c"
  316. fi
  317. if [ `wc -c ./src/menu.c | awk '{printf $1}'` -ne 5387 ]
  318. then
  319. echo `wc -c ./src/menu.c | awk '{print "Got " $1 ", Expected " 5387}'`
  320. fi
  321. if `test ! -s ./src/mods.c`
  322. then
  323. echo "writing ./src/mods.c"
  324. cat > ./src/mods.c << '\Rogue\Monster\'
  325.  
  326. /*
  327.  *  KTS.C
  328.  *
  329.  *  Additional DME commands written by Kevin T. Seghetti fixed up and
  330.  *  incorporated by Matt Dillon 17 April 1988.
  331.  */
  332.  
  333. #include "defs.h"
  334.  
  335. #define BLOCKDEPTH  5
  336. #define PINGDEPTH   10
  337.  
  338. static long BSstack[BLOCKDEPTH];
  339. static long BEstack[BLOCKDEPTH];
  340. static ED   *Bp[BLOCKDEPTH];
  341. static int  CurrDepth = 0;
  342.  
  343. static long PingLine[PINGDEPTH];
  344. static long PingCol[PINGDEPTH];
  345. static ED   *PingWin[PINGDEPTH];
  346.  
  347. void
  348. PMAdd()
  349. {
  350. }
  351.  
  352. void
  353. PMRem()
  354. {
  355. }
  356.  
  357. void
  358. PMKill(ep)
  359. ED *ep;
  360. {
  361.     register short i, j;
  362.  
  363.     for (i = 0; i < PINGDEPTH; ++i) {       /*  remove ping-pong marks  */
  364.     if (PingWin[i] == ep)
  365.         PingWin[i] = NULL;
  366.     }
  367.     for (i = j = 0; i < CurrDepth; ++i) {   /*  remove block marks      */
  368.     Bp[j] = Bp[i];
  369.     if (Bp[i] != ep)
  370.         ++j;
  371.     }
  372.     CurrDepth = j;
  373. }
  374.  
  375.  
  376. do_pushmark()
  377. {
  378.     text_sync();
  379.     if (blockok()) {
  380.     if (CurrDepth == BLOCKDEPTH) {
  381.         title("pushmark: stack limit reached");
  382.         return(-1);
  383.     }
  384.     BSstack[CurrDepth] = BSline;
  385.     BEstack[CurrDepth] = BEline;
  386.     Bp[CurrDepth] = BEp;
  387.  
  388.     ++CurrDepth;
  389.     text_redrawblock(0);
  390.     }
  391.     return(0);
  392. }
  393.  
  394. void
  395. do_popmark()
  396. {
  397.     text_sync();
  398.  
  399.     if (!CurrDepth) {           /*  no error message on purpose */
  400.     text_redrawblock(0);    /*  remove any existing block   */
  401.     return;
  402.     }
  403.     text_redrawblock(0);
  404.     --CurrDepth;
  405.     BSline = BSstack[CurrDepth];
  406.     BEline = BEstack[CurrDepth];
  407.     BEp = Bp[CurrDepth];
  408.     if (BEp == NULL || BEline >= BEp->Lines) {
  409.     BEp = NULL;
  410.     BSline = BEline = -1;
  411.     } else
  412.     text_redrawblock(1);
  413. }
  414.  
  415. void
  416. do_swapmark()
  417. {
  418.     register short i;
  419.     register long *ptmp;
  420.     register long tmp;
  421.  
  422.     if (do_pushmark() < 0)
  423.     return;
  424.     i = CurrDepth - 2;
  425.     if (i >= 0) {
  426.     ptmp = PingLine + i;
  427.     tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
  428.     ptmp = PingCol + i;
  429.     tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
  430.     ptmp = (long *)PingWin + i;
  431.     tmp = ptmp[0]; ptmp[0] = ptmp[1]; ptmp[1] = tmp;
  432.     }
  433.     do_popmark();
  434. }
  435.  
  436. do_purgemark()
  437. {
  438.     CurrDepth = 0;
  439. }
  440.  
  441. void
  442. do_ping()
  443. {
  444.     register uword num = atoi(av[1]);
  445.  
  446.     if (num >= PINGDEPTH) {
  447.     title("ping: out of range");
  448.     return;
  449.     }
  450.     PingLine[num]= Ep->Line;
  451.     PingCol[num] = Ep->Column;
  452.     PingWin[num] = Ep;
  453.     title("Line marked");
  454. }
  455.  
  456. void
  457. do_pong()
  458. {
  459.     register uword num = atoi(av[1]);
  460.     extern IBASE *IntuitionBase;
  461.  
  462.     text_sync();
  463.     if (num < 0 || num >= PINGDEPTH || !PingWin[num]) {
  464.     title("pong: range error or nothing marked");
  465.     return;
  466.     }
  467.     text_cursor(1);
  468.     text_switch(PingWin[num]->Win);
  469.     text_cursor(0);
  470.  
  471.     if (IntuitionBase->ActiveWindow != Ep->Win) {
  472.     WindowToFront(Ep->Win);
  473.     ActivateWindow(Ep->Win);
  474.     }
  475.     if ((Ep->Line = PingLine[num]) >= Ep->Lines) {
  476.     PingLine[num] = Ep->Line = Ep->Lines - 1;
  477.     }
  478.     Ep->Column = PingCol[num];
  479.     text_load();
  480.     text_sync();
  481. }
  482.  
  483. void
  484. do_undo()
  485. {
  486.     text_load();
  487.     text_redisplaycurrline();
  488. }
  489.  
  490. \Rogue\Monster\
  491. else
  492.   echo "will not over write ./src/mods.c"
  493. fi
  494. if [ `wc -c ./src/mods.c | awk '{printf $1}'` -ne 2857 ]
  495. then
  496. echo `wc -c ./src/mods.c | awk '{print "Got " $1 ", Expected " 2857}'`
  497. fi
  498. if `test ! -s ./src/rexxbind.asm`
  499. then
  500. echo "writing ./src/rexxbind.asm"
  501. cat > ./src/rexxbind.asm << '\Rogue\Monster\'
  502. * === rexxbind.asm =====================================================
  503. *
  504. * Copyright (c) 1986, 1987 by William S. Hawes (All Rights Reserved)
  505. *
  506. * ======================================================================
  507. * "Glue" routines for calling functions in the ARexx Systems Library.
  508. * All calls assume that the external _RexxSysBase has been set to the
  509. * ARexx SYstems library base by a call to OpenLibrary.
  510.  
  511.          INCLUDE  "rexx/storage.i"
  512.          INCLUDE  "rexx/rxslib.i"
  513.  
  514.          XREF     _RexxSysBase
  515.  
  516. * First calling convention:
  517. * 1, 2, or 3 parameters in (A0,A1,D0), return value in D0.
  518.  
  519.          ; msgptr = CreateRexxMsg(&replyport,&fileext,&hostname)
  520.  
  521.          XDEF     _CreateRexxMsg
  522. _CreateRexxMsg:
  523.          move.w   #_LVOCreateRexxMsg,d1
  524.          bra.s    CallSeq1
  525.  
  526.  
  527.          ; DeleteArgstring(argptr)
  528.  
  529.          XDEF     _DeleteArgstring
  530. _DeleteArgstring:
  531.          move.w   #_LVODeleteArgstring,d1
  532.          bra.s    CallSeq1
  533.  
  534.  
  535.          ; DeleteRexxMsg(msgptr)
  536.  
  537.          XDEF     _DeleteRexxMsg
  538. _DeleteRexxMsg:
  539.          move.w   #_LVODeleteRexxMsg,d1
  540.          bra.s    CallSeq1
  541.  
  542.  
  543.          ; FreePort(&msgport)
  544.  
  545.          XDEF     _FreePort
  546. _FreePort:
  547.          move.w   #_LVOFreePort,d1
  548.          bra.s    CallSeq1
  549.  
  550.  
  551.          ; signal = InitPort(&replyport)
  552.  
  553.          XDEF     _InitPort
  554. _InitPort:
  555.          move.w   #_LVOInitPort,d1
  556.          bra.s    CallSeq1
  557.  
  558.  
  559.          ; boolean = IsRexxMsg(msgptr)
  560.  
  561.          XDEF     _IsRexxMsg
  562. _IsRexxMsg:
  563.          move.w   #_LVOIsRexxMsg,d1
  564.          bra.s    CallSeq1
  565.  
  566.  
  567.          ; Load three arguments into (A0,A1,D0)
  568.  
  569. CallSeq1 movea.l  4(sp),a0
  570.          movea.l  8(sp),a1
  571.          move.l   12(sp),d0
  572.  
  573.  
  574.          ; Call the library function
  575.  
  576. CallFunc move.l   a6,-(sp)
  577.          movea.l  _RexxSysBase,a6
  578.          jsr      0(a6,d1.w)
  579.          movea.l  (sp)+,a6
  580.          rts
  581.  
  582.  
  583. * Second calling convention:  2 parameters in (A0,D0), return value in D0.
  584.  
  585.          ; argptr = CreateArgstring(&string,length)
  586.  
  587.          XDEF     _CreateArgstring
  588. _CreateArgstring:
  589.          moveq    #_LVOCreateArgstring,d1
  590.          bra.s    CallSeq2
  591.  
  592.  
  593.          ; ClearMem(address,length)
  594.  
  595.          XDEF     _ClearMem
  596. _ClearMem:
  597.          move.w   #_LVOClearMem,d1
  598.          bra.s    CallSeq2
  599.  
  600.  
  601.          ; Load two arguments (A0,D0)
  602.  
  603. CallSeq2 movea.l  4(sp),a0
  604.          move.l   8(sp),d0
  605.          bra      CallFunc
  606.  
  607.          END
  608.  
  609. \Rogue\Monster\
  610. else
  611.   echo "will not over write ./src/rexxbind.asm"
  612. fi
  613. if [ `wc -c ./src/rexxbind.asm | awk '{printf $1}'` -ne 2357 ]
  614. then
  615. echo `wc -c ./src/rexxbind.asm | awk '{print "Got " $1 ", Expected " 2357}'`
  616. fi
  617. if `test ! -s ./src/command.c`
  618. then
  619. echo "writing ./src/command.c"
  620. cat > ./src/command.c << '\Rogue\Monster\'
  621.  
  622. /*
  623.  * COMMAND.C
  624.  *
  625.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  626.  *
  627.  * )c             single character (typing)
  628.  * 'c                single character (typing)
  629.  * `string'          string of characters w/ embedded `' allowed!
  630.  * (string)             same thing w/ embedded () allowed!
  631.  * \c             override
  632.  *
  633.  * name arg arg      command name. The arguments are interpreted as strings
  634.  *             for the command.
  635.  *
  636.  * $scanf         macro insert scanf'd variable
  637.  * $filename         macro insert current file name
  638.  *
  639.  * Any string arguments not part of a command are considered to be typed
  640.  * text.
  641.  */
  642.  
  643. #include "defs.h"
  644. #include <stdio.h>
  645.  
  646. #if AREXX
  647. extern int foundcmd;       /* control for implicit ARexx macro invocation   */
  648. extern int cmderr;       /* global command error flag for do_rexx()'s use */
  649. #endif
  650.  
  651. #define CF_COK    1   /*    Can be executed while in command line mode    */
  652. #define CF_PAR    2   /*    ESCIMM special flag.. save rest of command line */
  653.             /*    so it can be executed after user entry        */
  654.  
  655. #define CF_ICO    4   /*    OK to execute if iconified, else uniconify first*/
  656.  
  657. extern char *breakout();
  658.  
  659. typedef struct {
  660.    char *name;        /* command name      */
  661.    ubyte args;
  662.    ubyte flags;
  663.    int (*func)();   /* function           */
  664. } COMM;
  665.  
  666. extern int  do_map(),       do_unmap(),     do_up(),        do_down(),
  667.         do_left(),      do_right(),     do_return(),    do_bs(),
  668.         do_del(),       do_esc(),       do_downadd(),   do_lastcolumn(),
  669.         do_firstcolumn(),do_edit(),     do_tab(),       do_backtab(),
  670.         do_save(),      do_saveas(),    do_deline(),    do_insline(),
  671.         do_top(),       do_bottom(),    do_source(),    do_firstnb(),
  672.         do_quit(),      do_find(),      do_page(),      do_savetabs(),
  673.         do_split(),     do_goto(),      do_screentop(), do_screenbottom(),
  674.         do_join(),      do_repeat(),    do_tabstop(),   do_insertmode(),
  675.         do_block(),     do_bdelete(),   do_bcopy(),     do_bmove(),
  676.         do_bsave(),     do_wleft(),     do_wright(),    do_remeol(),
  677.         do_savemap(),   do_toggle(),    do_if(),        do_tlate(),
  678.         do_bsource(),   do_findr(),     do_findstr(),   do_newwindow(),
  679.         do_windowparm(),do_resize(),    do_margin(),    do_wordwrap(),
  680.         do_reformat(),  do_execute(),   do_chfilename(),do_scrollup(),
  681.         do_scrolldown(),do_recall(),    do_scanf(),     do_iconify(),
  682.         do_tomouse(),   do_refs(),      do_arpload(),   do_arpsave(),
  683.         do_arpinsfile(),do_setfont(),   do_ignorecase(),do_ctags(),
  684.         do_addpath(),   do_rempath(),   do_set(),       do_setenv(),
  685.         do_unset(),     do_unsetenv(),  do_ipc(),       do_cd();
  686.  
  687. extern int  do_menu(), do_menuclear(), do_menuadd(), do_menudel(),
  688.         do_menudelhdr(), do_menuon(), do_menuoff();
  689.  
  690. extern int  do_null(), do_rx();
  691.  
  692. extern int  do_pushmark(),  do_popmark(),   do_swapmark(),  do_purgemark(),
  693.         do_ping(),      do_pong(),      do_undo();
  694.  
  695. #if AREXX
  696. extern int  do_rx(),        do_rx1(),       do_rx2();
  697. #endif
  698.  
  699. /*============================================================================*/
  700.  
  701. /*
  702.  *  WLEFT/WRIGHT will check command line mode themselves, and thus can
  703.  *  be marked flags=1 even though they can change the line number.
  704.  *
  705.  *  No more than 255 commands may exist unless you change the type of hindex[]
  706.  *
  707.  *  Command names MUST be sorted by their first character
  708.  */
  709.  
  710. unsigned char hindex[26];   /*    alpha hash into table    */
  711.  
  712.     /*      args flags    */
  713.  
  714. COMM Comm[] = {
  715. #ifndef NO_DO2
  716.     "addpath",       1, CF_COK, do_addpath,
  717. #endif
  718.     "arpinsfile",    0,      0, do_arpinsfile,
  719.     "arpload",       0,      0, do_arpload,
  720.     "arpsave",       0,      0, do_arpsave,
  721.     "back",          0, CF_COK, do_bs,
  722.     "backtab",       0, CF_COK, do_backtab,
  723.     "bcopy",         0,      0, do_bcopy,
  724.     "bdelete",       0,      0, do_bdelete,
  725.     "block",         0,      0, do_block,    /* checks com name for mode */
  726.     "bmove",         0,      0, do_bmove,
  727.     "bottom",        0,      0, do_bottom,
  728.     "bs",            0, CF_COK, do_bs,
  729.     "bsave",         1, CF_COK, do_bsave,
  730.     "bsource",       0,      0, do_bsource,
  731.     "cd",            1, CF_COK, do_cd,
  732.     "chfilename",    1,      0, do_chfilename,
  733. #ifndef NO_DO_CTAGS
  734.     "ctags",         0, CF_ICO, do_ctags,
  735. #endif
  736.     "del",           0, CF_COK, do_del,
  737.     "deline",        0,      0, do_deline,
  738.     "down",          0,      0, do_down,
  739.     "downadd",       0,      0, do_downadd,
  740.     "esc",           0, CF_COK, do_esc,
  741.     "escimm",        1, CF_PAR, do_esc,
  742.     "execute",       1, CF_ICO, do_execute,
  743.     "find",          1,      0, do_find,     /* checks com name for mode */
  744.     "findr",         2,      0, do_findr,    /* checks com name for mode */
  745.     "findstr",       1, CF_COK, do_findstr,  /* checks com name for mode */
  746.     "first",         0, CF_COK, do_firstcolumn,
  747.     "firstnb",       0, CF_COK, do_firstnb,
  748.     "goto",          1,      0, do_goto,
  749.     "height",        1, CF_COK, do_windowparm,
  750.     "iconify",       0, CF_ICO, do_iconify,
  751.     "if",            2, CF_COK, do_if,
  752.     "ifelse",        3, CF_COK, do_if,
  753.     "ignorecase",    1, CF_COK, do_ignorecase,
  754.     "insertmode",    1, CF_COK, do_insertmode,
  755.     "insfile",       1,      0, do_edit,
  756.     "insline",       0,      0, do_insline,
  757.     "ipc",           3, CF_COK, do_ipc,
  758.     "join",          0,      0, do_join,
  759.     "last",          0, CF_COK, do_lastcolumn,
  760.     "left",          0, CF_COK, do_left,
  761.     "leftedge",      1, CF_COK, do_windowparm,
  762.     "map",           2, CF_COK, do_map,
  763.     "margin",        1, CF_COK, do_margin,
  764.     "menuon",        0,      0, do_menuon,
  765.     "menuoff",       0,      0, do_menuoff,
  766.     "menuadd",       3,      0, do_menuadd,
  767.     "menudel",       2,      0, do_menudel,
  768.     "menudelhdr",    1,      0, do_menudelhdr,
  769.     "menuclear",     0,      0, do_menuclear,
  770.     "newfile",       1,      0, do_edit,     /* checks com name for mode */
  771.     "newwindow",     0, CF_ICO, do_newwindow,
  772.     "next",          0,      0, do_find,
  773.     "nextr",         0,      0, do_findr,
  774.     "null",          0, CF_COK, do_null,
  775.     "pagedown",      0,      0, do_page,
  776.     "pageset",       1,      0, do_page,
  777.     "pageup",        0,      0, do_page,
  778.     "ping",          1, CF_ICO, do_ping,
  779.     "pong",          1,      0, do_pong,
  780.     "prev",          0,      0, do_find,
  781.     "prevr",         0,      0, do_findr,
  782.     "popmark",       0,      0, do_popmark,
  783.     "purgemark",     0,      0, do_purgemark,
  784.     "pushmark",      0,      0, do_pushmark,
  785.     "quit",          0, CF_ICO, do_quit,
  786.     "recall",        0, CF_COK, do_recall,
  787. #ifndef NO_DO_REF
  788.     "ref",           0,      0, do_refs,
  789. #endif
  790.     "reformat",      0,      0, do_reformat,
  791.     "remeol",        0, CF_COK, do_remeol,
  792. #ifndef NO_DO2
  793.     "rempath",       1, CF_COK, do_rempath,
  794. #endif
  795.     "repeat",        2, CF_ICO|CF_COK, do_repeat,
  796.     "repstr",        1, CF_COK, do_findstr,
  797.     "resettoggle",   1, CF_COK, do_toggle,
  798.     "resize",        2,      0, do_resize,
  799.     "return",        0, CF_COK, do_return,   /* special meaning in command line mode */
  800.     "right",         0, CF_COK, do_right,
  801. #if AREXX
  802.     "rx",            1,      0, do_rx,       /* explicit ARexx macro invocation      */
  803.     "rx1",           2,      0, do_rx1,      /* explicit, with 1 arg  to ARexx macro */
  804.     "rx2",           3,      0, do_rx2,      /* explicit, with 2 args to ARexx macro */
  805. #endif
  806.     "saveas",        1, CF_ICO|CF_COK, do_saveas,
  807.     "savemap",       1, CF_ICO|CF_COK, do_savemap,  /* checks com name for mode */
  808.     "saveold",       0, CF_ICO|CF_COK, do_save,
  809.     "savesmap",      1, CF_ICO|CF_COK, do_savemap,
  810.     "savetabs",      1, CF_ICO|CF_COK, do_savetabs,
  811.     "scanf",         1, CF_COK, do_scanf,
  812.     "screenbottom",  0,      0, do_screenbottom,
  813.     "screentop",     0,      0, do_screentop,
  814.     "scrollup",      0,      0, do_scrollup,
  815.     "scrolldown",    0,      0, do_scrolldown,
  816.     "set",           2, CF_ICO|CF_COK, do_set,
  817.     "setenv",        2, CF_ICO|CF_COK, do_setenv,
  818.     "setfont",       2,      0, do_setfont,
  819.     "settoggle",     1, CF_COK, do_toggle,
  820.     "source",        1, CF_COK, do_source,
  821.     "split",         0,      0, do_split,
  822.     "swapmark",      0,      0, do_swapmark,
  823.     "tab",           0, CF_COK, do_tab,
  824.     "tabstop",       1, CF_COK, do_tabstop,
  825.     "tlate",         1, CF_COK, do_tlate,
  826.     "tmpheight",     1, CF_COK, do_windowparm,
  827.     "tmpwidth",      1, CF_COK, do_windowparm,
  828.     "toggle",        1, CF_COK, do_toggle,
  829.     "tomouse",       0,      0, do_tomouse,
  830.     "top",           0,      0, do_top,
  831.     "topedge",       1, CF_COK, do_windowparm,
  832.     "unblock",       0,      0, do_block,
  833.     "undo",          0,      0, do_undo,
  834.     "unmap",         1, CF_ICO|CF_COK, do_unmap,
  835.     "unset",         1, CF_ICO|CF_COK, do_unset,
  836.     "unsetenv",      1, CF_ICO|CF_COK, do_unsetenv,
  837.     "up",            0,      0, do_up,
  838.     "while",         2, CF_ICO|CF_COK, do_if,
  839.     "width",         1, CF_COK, do_windowparm,
  840.     "wleft",         0, CF_COK, do_wleft,
  841.     "wordwrap",      1, CF_COK, do_wordwrap,
  842.     "wright",        0, CF_COK, do_wright,
  843.     NULL, 0, 0, NULL
  844. };
  845.  
  846. init_command()
  847. {
  848.     register short hi;
  849.     register COMM *comm;
  850.  
  851.     hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
  852.     comm = Comm + hi;
  853.  
  854.     while (hi >= 0) {
  855.     hindex[comm->name[0] - 'a'] = hi;
  856.     --hi;
  857.     --comm;
  858.     }
  859. }
  860.  
  861. #define MAXIA    5
  862.  
  863. do_command(str)
  864. char *str;
  865. {
  866.     register char *arg;
  867.     char *aux1, *aux2;
  868.     char *repstr[MAXIA];
  869.     char quoted;
  870.     short repi = 0;
  871.     register short i, j;
  872.     static int level;
  873.  
  874.     if (++level > 20) {
  875.     title("Recursion Too Deep!");
  876.     --level;
  877. #if AREXX
  878.     foundcmd = 1;    /* to prevent us from trying an ARexx macro */
  879. #endif
  880.     return(0);
  881.     }
  882.     while (arg = breakout(&str, "ed, &aux1)) {
  883.     if (quoted) {
  884.         if (Ep->iconmode)
  885.         uniconify();
  886.         text_write(arg);
  887.         goto loop;
  888.     }
  889.     for (i = 0; arg[i]; ++i) {
  890.         if (arg[i] >= 'A' && arg[i] <= 'Z')
  891.         arg[i] += 'a' - 'A';
  892.     }
  893.  
  894.     if (arg[0] >= 'a' && arg[0] <= 'z') {
  895.         register COMM *comm = &Comm[hindex[arg[0]-'a']];
  896.         for (; comm->name && comm->name[0] == arg[0]; ++comm) {
  897.         if (strcmp(arg, comm->name) == 0) {
  898. #if AREXX
  899.             foundcmd = 1;
  900. #endif
  901.             av[0] = (ubyte *)comm->name;
  902.             for (j = 1; j <= comm->args; ++j) {
  903.             av[j] = (ubyte *)breakout(&str, "ed, &aux2);
  904.             if (aux2) {
  905.                 if (repi == MAXIA) {
  906.                 free(aux2);
  907.                 title("Command too complex");
  908.                 goto fail;
  909.                 } else {
  910.                 repstr[repi++] = aux2;
  911.                 }
  912.             }
  913.             if (!av[j]) {
  914.                 title("Bad argument");
  915.                 goto fail;
  916.             }
  917.             }
  918.             av[j] = NULL;   /* end of arglist */
  919.             if ((comm->flags & CF_COK) || !Comlinemode) {
  920.             if (comm->flags & CF_PAR) {
  921.                 if (Partial)
  922.                 free(Partial);
  923.                 Partial = (char *)malloc(strlen(str)+1);
  924.                 strcpy(Partial, str);
  925.                 str += strlen(str);     /*  skip string */
  926.             }
  927.             if (Ep->iconmode && !(comm->flags & CF_ICO))
  928.                 uniconify();
  929.             (*comm->func)(-1);
  930.             }
  931.             if (Abortcommand)
  932.             goto fail;
  933.             goto loop;
  934.         }
  935.         }
  936.     }
  937.  
  938.     /* Command not found, check for macro    */
  939.  
  940.     {
  941.         char *str;
  942.         int ret;
  943.         if ((str = keyspectomacro(arg)) || (str = menutomacro(arg))) {
  944.         str = (char *)strcpy(malloc(strlen(str)+1), str);
  945.         ret = do_command(str);
  946.         free(str);
  947. #if AREXX
  948.         if (ret) {
  949.             foundcmd = 1;   /* dunno about this yet for ARexx macros */
  950.             goto loop;
  951.         }
  952. #else
  953.         if (ret)
  954.             goto loop;
  955. #endif
  956.         goto fail;
  957.         }
  958.     }
  959.  
  960.     /* Command still not found, check for public macro  */
  961.     /* code to be added */
  962.  
  963. #if AREXX
  964.     do_rxImplied(arg, str);
  965. #else
  966.     title("Unknown Command");
  967. #endif
  968. fail:
  969.     --level;
  970.     while (--repi >= 0)
  971.         free(repstr[repi]);
  972.     if (aux1)
  973.         free(aux1);
  974.     return(0);
  975. loop:
  976.     if (aux1)
  977.         free(aux1);
  978.     }
  979.     --level;
  980.     while (--repi >= 0)
  981.     free(repstr[repi]);
  982.     return(1);
  983. }
  984.  
  985. do_null()
  986. {
  987. }
  988.  
  989. do_source()
  990. {
  991.     char buf[256];
  992.     long xfi;
  993.     register char *str;
  994.     long oldlock = CurrentDir(DupLock(Ep->dirlock));
  995.  
  996.     if (xfi = xfopen(av[1], "r", 512)) {
  997.     while (xfgets(xfi, buf, 256) >= 0) {
  998.         if (buf[0] == '#')
  999.         continue;
  1000.         for (str = buf; *str; ++str) {
  1001.         if (*str == 9)
  1002.             *str = ' ';
  1003.         }
  1004.         do_command(buf);
  1005.     }
  1006.     xfclose(xfi);
  1007.     } else {
  1008.     if (av[0])
  1009.         title("File not found");
  1010.     }
  1011.     UnLock(CurrentDir(oldlock));
  1012. }
  1013.  
  1014.  
  1015. do_quit()
  1016. {
  1017.     extern char Quitflag;
  1018.  
  1019.     Quitflag = 1;
  1020. }
  1021.  
  1022. do_execute()
  1023. {
  1024.     long oldlock = CurrentDir(Ep->dirlock);
  1025.  
  1026.     Execute(av[1], NULL, NULL);
  1027.     CurrentDir(oldlock);
  1028. }
  1029.  
  1030. /*
  1031.  * repeat X command
  1032.  *
  1033.  * Since repeat takes up 512+ stack, it should not be nested more than
  1034.  * twice.
  1035.  *
  1036.  * (if X is not a number it can be abbr. with 2 chars)
  1037.  *
  1038.  * X =    N     -number of repeats
  1039.  *    line  -current line # (lines begin at 1)
  1040.  *    lbot  -#lines to the bottom, inc. current
  1041.  *    cleft -column # (columns begin at 0)
  1042.  *        (thus is also chars to the left)
  1043.  *    cright-#chars to eol, including current char
  1044.  *    tr    -#char positions to get to next tab stop
  1045.  *    tl    -#char positions to get to next backtab stop
  1046.  */
  1047.  
  1048. #define SC(a,b) ((a)<<8|(b))
  1049.  
  1050. do_repeat()
  1051. {
  1052.     register ubyte *ptr = av[1];
  1053.     register unsigned long n;
  1054.     char buf1[256];
  1055.     char buf2[256];
  1056.  
  1057.     breakreset();
  1058.     strcpy(buf1, av[2]);
  1059.     switch((ptr[0]<<8)+ptr[1]) {
  1060.     case SC('l','i'):
  1061.     n = text_lineno();
  1062.     break;
  1063.     case SC('l','b'):
  1064.     n = text_lines() - text_lineno() + 1;
  1065.     break;
  1066.     case SC('c','l'):
  1067.     n = text_colno();
  1068.     break;
  1069.     case SC('c','r'):
  1070.     n = text_cols() - text_colno();
  1071.     break;
  1072.     case SC('t','r'):
  1073.     n = text_tabsize()-(text_colno() % text_tabsize());
  1074.     break;
  1075.     case SC('t','l'):
  1076.     n = text_colno() % text_tabsize();
  1077.     if (n == 0)
  1078.         n = text_tabsize();
  1079.     break;
  1080.     default:
  1081.     n = atoi(av[1]);
  1082.     break;
  1083.     }
  1084.     while (n > 0) {
  1085.     strcpy(buf2, buf1);
  1086.     if (do_command(buf2) == 0 || breakcheck()) {
  1087.         Abortcommand = 1;
  1088.         break;
  1089.     }
  1090.     --n;
  1091.     }
  1092. }
  1093.  
  1094. /*
  1095.  *  BREAKOUT()
  1096.  *
  1097.  *  Break out the next argument.  The argument is space delimited and
  1098.  *  might be quoted with `' or (), or single quoted as 'c or )c
  1099.  *
  1100.  *  Also:    $var        -variable insertion
  1101.  *        ^c        -control character
  1102.  */
  1103.  
  1104. char *
  1105. breakout(ptr, quoted, paux)
  1106. register char **ptr;
  1107. char **paux;
  1108. char *quoted;
  1109. {
  1110.     register char *str = *ptr;
  1111.     char *base;
  1112.     short count = 0;
  1113.     char opc = 0;
  1114.     char clc = 0;
  1115.     char immode = 0;
  1116.     char isaux = 0;
  1117.     char buf[256];
  1118.     short di = 0;
  1119.  
  1120.     *quoted = 0;
  1121.     *paux = NULL;
  1122.     while (*str == ' ')
  1123.     ++str;
  1124.     if (!*str)
  1125.     return(NULL);
  1126.  
  1127.     *ptr = str;
  1128.     base = str;
  1129.     while (*str) {
  1130.     if (immode) {
  1131.         if (di != sizeof(buf)-1)
  1132.         buf[di++] = *str;
  1133.         ++str;
  1134.         continue;
  1135.     }
  1136.     if (count == 0) {
  1137.         if (*str == ' ')
  1138.         break;
  1139.         if (*str == '\'' || *str == ')')
  1140.         clc = *str;
  1141.         if (*str == '`') {
  1142.         opc = '`';
  1143.         clc = '\'';
  1144.         }
  1145.         if (*str == '(') {
  1146.         opc = '(';
  1147.         clc = ')';
  1148.         }
  1149.     }
  1150.     if (*str == opc) {
  1151.         ++count;
  1152.         if (str == *ptr) {
  1153.         *quoted = 1;
  1154.         base = ++str;
  1155.         continue;
  1156.         }
  1157.     }
  1158.     if (*str == clc) {
  1159.         --count;
  1160.         if (count == 0 && *quoted)     /*  end of argument     */
  1161.         break;
  1162.         if (str == *ptr && count < 0) {
  1163.         immode = 1;
  1164.         *quoted = 1;
  1165.         base = ++str;
  1166.         continue;
  1167.         }
  1168.     }
  1169.  
  1170.     /*
  1171.      *  $varname $(varname) $`varname'.  I.E. three forms are allowed,
  1172.      *  which allows one to insert the string almost anywhere.  The
  1173.      *  first form names are limited to alpha-numerics, '-', and '_'.
  1174.      */
  1175.  
  1176.     if (*str == '$') {
  1177.         register char *ptr;
  1178.         char c, ce;
  1179.         short len;
  1180.  
  1181.         ce = 0;                /*    first form  */
  1182.         ++str;                /*    skip $        */
  1183.         if (*str == '(') {              /*  second form */
  1184.         ce = ')';
  1185.         ++str;
  1186.         } else if (*str == '`') {       /*  third form  */
  1187.         ce = '\'';
  1188.         ++str;
  1189.         }
  1190.         ptr = str;                /*    start of varname    */
  1191.         if (ce) {                       /*  until end char OR   */
  1192.         while (*ptr && *ptr != ce)
  1193.             ++ptr;
  1194.         } else {                /*    smart end-varname   */
  1195.         while ((*ptr >= 'a' && *ptr <= 'z') ||
  1196.             (*ptr >= 'A' && *ptr <= 'Z') ||
  1197.             (*ptr >= '0' && *ptr <= '9') ||
  1198.             *ptr == '-' || *ptr == '_' ) {
  1199.             ++ptr;
  1200.         }
  1201.         }
  1202.         len = ptr - str;            /*    length of variable  */
  1203.  
  1204.         c = *ptr; *ptr = 0;         /*    temp. terminate \0  */
  1205.         if (strcmp(str, "scanf") == 0) {
  1206.         *ptr = c;
  1207.         isaux = 1;
  1208.         if (di + strlen(String) < sizeof(buf)-1) {
  1209.             strcpy(buf + di, String);
  1210.             di += strlen(buf + di);
  1211.         }
  1212.         str += len;            /*    next string pos     */
  1213.         if (ce)
  1214.             ++str;
  1215.         continue;
  1216.         }
  1217.         if (strcmp(str, "filename") == 0) {
  1218.         *ptr = c;
  1219.         isaux = 1;
  1220.         if (di + strlen(Ep->Name) < sizeof(buf)-1) {
  1221.             strcpy(buf + di, Ep->Name);
  1222.             di += strlen(buf + di);
  1223.         }
  1224.         str += len;
  1225.         if (ce)
  1226.             ++str;
  1227.         continue;
  1228.         }
  1229.         if (strcmp(str, "colno") == 0) {
  1230.         *ptr = c;
  1231.         isaux = 1;
  1232.         if (di < sizeof(buf)-8) {
  1233.             sprintf(buf + di, "%ld", Ep->Column + 1);
  1234.             di += strlen(buf + di);
  1235.         }
  1236.         str += len;
  1237.         if (ce)
  1238.             ++str;
  1239.         continue;
  1240.         }
  1241.         if (strcmp(str, "lineno") == 0) {
  1242.         *ptr = c;
  1243.         isaux = 1;
  1244.         if (di < sizeof(buf)-8) {
  1245.             sprintf(buf + di, "%ld", Ep->Line + 1);
  1246.             di += strlen(buf + di);
  1247.         }
  1248.         str += len;
  1249.         if (ce)
  1250.             ++str;
  1251.         continue;
  1252.         }
  1253.         if (ptr = getvar(str)) {
  1254.         str[len] = c;
  1255.         isaux = 1;
  1256.         if (di + strlen(ptr) < sizeof(buf)-1) {
  1257.             strcpy(buf + di, ptr);
  1258.             di += strlen(buf + di);
  1259.         }
  1260.         str += len;
  1261.         if (ce)
  1262.             ++str;
  1263.         free(ptr);
  1264.         continue;
  1265.         }
  1266.         *ptr = c;
  1267.         --str;
  1268.         if (ce)
  1269.         --str;
  1270.     }
  1271.     if (*str == '^' && (str[1] & 0x1F)) {
  1272.         ++str;
  1273.         *str &= 0x1F;
  1274.         isaux = 1;
  1275.     }
  1276.     if (*str == '\\' && str[1]) {
  1277.         ++str;
  1278.         isaux = 1;
  1279.     }
  1280.     buf[di++] = *str++;
  1281.     }
  1282.     buf[di++] = 0;
  1283.     if (isaux) {
  1284.     *paux = malloc(di);
  1285.     strcpy(*paux, buf);
  1286.     base = *paux;
  1287.     }
  1288.     if (*str) {             /*  space ended */
  1289.     *str = '\0';
  1290.     *ptr = str + 1;     /*    next arg    */
  1291.     } else {
  1292.     *ptr = str;        /*    last arg    */
  1293.     }
  1294.     return(base);
  1295. }
  1296.  
  1297.  
  1298. \Rogue\Monster\
  1299. else
  1300.   echo "will not over write ./src/command.c"
  1301. fi
  1302. if [ `wc -c ./src/command.c | awk '{printf $1}'` -ne 17738 ]
  1303. then
  1304. echo `wc -c ./src/command.c | awk '{print "Got " $1 ", Expected " 17738}'`
  1305. fi
  1306. if `test ! -s ./src/cmd3.c`
  1307. then
  1308. echo "writing ./src/cmd3.c"
  1309. cat > ./src/cmd3.c << '\Rogue\Monster\'
  1310.  
  1311. /*
  1312.  * CMD3.C
  1313.  *
  1314.  *    (C)Copyright 1988 by Matthew Dillon, All Rights Reserved
  1315.  *
  1316.  *  SETFONT
  1317.  *  IGNORECASE
  1318.  *  SET
  1319.  *  SETENV
  1320.  *  UNSET
  1321.  *  UNSETENV
  1322.  *  CD
  1323.  */
  1324.  
  1325. #include "defs.h"
  1326. #include <local/xmisc.h>
  1327. #include <stdio.h>
  1328.  
  1329. #define nomemory()  { memoryfail = 1; }
  1330.  
  1331. extern FONT *GetFont();
  1332.  
  1333. /*
  1334.  *  SETFONT font size
  1335.  */
  1336.  
  1337. void
  1338. do_setfont()
  1339. {
  1340.     register FONT *font = GetFont(av[1], atoi(av[2]));
  1341.     register ED *ep = Ep;
  1342.     if (font) {
  1343.     if (ep->Font)
  1344.         CloseFont(ep->Font);
  1345.     ep->Font = font;
  1346.     SetFont(ep->Win->RPort, font);
  1347.     SetRast(ep->Win->RPort, 0);
  1348.     RefreshWindowFrame(ep->Win);
  1349.     set_window_params();
  1350.     text_redisplay();
  1351.     } else {
  1352.     title("Unable to find font");
  1353.     }
  1354. }
  1355.  
  1356. do_ignorecase()
  1357. {
  1358.     register ED *ep = Ep;
  1359.  
  1360.     if (av[1][0]) {
  1361.     switch(av[1][1] & 0x1F) {
  1362.     case 'n'&0x1F:
  1363.         ep->IgnoreCase = 1;
  1364.         break;
  1365.     case 'f'&0x1F:
  1366.         ep->IgnoreCase = 0;
  1367.         break;
  1368.     case 'o'&0x1F:
  1369.         ep->IgnoreCase = 1 - ep->IgnoreCase;
  1370.         break;
  1371.     }
  1372.     if (ep->IgnoreCase)
  1373.         title("Case InSensitive");
  1374.     else
  1375.         title("Case Sensitive");
  1376.     }
  1377. }
  1378.  
  1379. /*
  1380.  *  av[1]
  1381.  */
  1382.  
  1383. do_cd()
  1384. {
  1385.     long oldlock;
  1386.     long lock;
  1387.  
  1388.     oldlock = CurrentDir(Ep->dirlock);
  1389.     if (lock = Lock(av[1], SHARED_LOCK)) {
  1390.     UnLock(CurrentDir(oldlock));
  1391.     Ep->dirlock = lock;
  1392.     } else {
  1393.     CurrentDir(oldlock);
  1394.     Abortcommand = 1;
  1395.     title("Unable to CD");
  1396.     }
  1397. }
  1398.  
  1399. /*
  1400.  *  VARIABLE SUPPORT!
  1401.  */
  1402.  
  1403. #define VARS    struct _VARS
  1404. VARS {
  1405.     MNODE   Node;
  1406.     char    *Name;
  1407.     char    *Str;
  1408. };
  1409.  
  1410. static MLIST SList = { (MNODE *)&SList.mlh_Tail, NULL, (MNODE *)&SList.mlh_Head };
  1411.  
  1412. void
  1413. do_set()
  1414. {
  1415.     register VARS *v;
  1416.  
  1417.     do_unset();
  1418.     if (v = malloc(sizeof(VARS))) {
  1419.     if (v->Name = malloc(strlen(av[1])+1)) {
  1420.         if (v->Str = malloc(strlen(av[2])+1)) {
  1421.         AddHead(&SList, v);
  1422.         strcpy(v->Name, av[1]);
  1423.         strcpy(v->Str , av[2]);
  1424.         return;
  1425.         }
  1426.         free(v->Name);
  1427.     }
  1428.     free(v);
  1429.     }
  1430.     nomemory();
  1431. }
  1432.  
  1433. do_setenv()
  1434. {
  1435.     SetDEnv(av[1], av[2]);
  1436. }
  1437.  
  1438. do_unset()
  1439. {
  1440.     register VARS *v;
  1441.  
  1442.     for (v = (VARS *)SList.mlh_Head; v->Node.mln_Succ; v = (VARS *)v->Node.mln_Succ) {
  1443.     if (strcmp(v->Name, av[1]) == 0) {
  1444.         Remove(v);
  1445.         free(v);
  1446.         free(v->Name);
  1447.         free(v->Str);
  1448.         break;
  1449.     }
  1450.     }
  1451. }
  1452.  
  1453. do_unsetenv()
  1454. {
  1455.     register char *ptr = (char *)av[1];
  1456.     register char *tmp = malloc(4+strlen(ptr)+1);
  1457.  
  1458.     if (tmp) {
  1459.     strcpy(tmp, "ENV:");
  1460.     strcat(tmp, ptr);
  1461.     mountrequest(0);
  1462.     DeleteFile(tmp);
  1463.     mountrequest(1);
  1464.     free(tmp);
  1465.     }
  1466. }
  1467.  
  1468. /*
  1469.  *  Search (1) internal list, (2) enviroment, (3) macros.  The variable
  1470.  *  is allocated with malloc().  NULL if not found.  ENV: need not exist.
  1471.  */
  1472.  
  1473. char *
  1474. getvar(find)
  1475. char *find;
  1476. {
  1477.     register char *str = NULL;
  1478.     {
  1479.     register VARS *v;
  1480.  
  1481.     for (v = (VARS *)SList.mlh_Head; v->Node.mln_Succ; v = (VARS *)v->Node.mln_Succ) {
  1482.         if (strcmp(v->Name, find) == 0) {
  1483.         if (str = malloc(strlen(v->Str)+1)) {
  1484.             strcpy(str, v->Str);
  1485.             return(str);
  1486.         }
  1487.         }
  1488.     }
  1489.     }
  1490.  
  1491.     mountrequest(0);
  1492.     str = GetDEnv(find);
  1493.     mountrequest(1);
  1494.     if (str)
  1495.     return(str);
  1496.  
  1497.     if ((str = keyspectomacro(find)) || (str = menutomacro(find))) {
  1498.     register char *ptr = malloc(strlen(str)+1);
  1499.     if (ptr) {
  1500.         strcpy(ptr, str);
  1501.         return(ptr);
  1502.     }
  1503.     }
  1504.     return(NULL);
  1505. }
  1506.  
  1507. \Rogue\Monster\
  1508. else
  1509.   echo "will not over write ./src/cmd3.c"
  1510. fi
  1511. if [ `wc -c ./src/cmd3.c | awk '{printf $1}'` -ne 3166 ]
  1512. then
  1513. echo `wc -c ./src/cmd3.c | awk '{print "Got " $1 ", Expected " 3166}'`
  1514. fi
  1515. if `test ! -s ./src/keyboard.c`
  1516. then
  1517. echo "writing ./src/keyboard.c"
  1518. cat > ./src/keyboard.c << '\Rogue\Monster\'
  1519.  
  1520. /*
  1521.  *  KEYBOARD.C
  1522.  *
  1523.  *    (C)Copyright 1987 by Matthew Dillon
  1524.  *
  1525.  *  Handle keyboard related stuff such as keyboard mappings.  Every time
  1526.  *  a key is pressed, KEYCTL() is called with the code.  KEYCTL() remembers
  1527.  *  which qualifier keys are currently held down, and when a non-qualifier
  1528.  *  key is pressed finds the hash entry for the key.  If no hash entry
  1529.  *  exists (e.g. you type a normal 'a') the default keymap is used.
  1530.  */
  1531.  
  1532. #include "defs.h"
  1533. #include <stdio.h>
  1534.  
  1535. extern ubyte *cqtoa();
  1536.  
  1537. typedef struct IOStdReq CIO;
  1538.  
  1539. #define QUAL_SHIFT   0x01
  1540. #define QUAL_CTRL    0x02
  1541. #define QUAL_AMIGA   0x04
  1542. #define QUAL_ALT     0x08
  1543. #define QUAL_LMB     0x10
  1544. #define QUAL_MMB     0x20
  1545. #define QUAL_RMB     0x40
  1546.  
  1547. #define HASHSIZE  64            /*    power of 2  */
  1548. #define HASHMASK  (HASHSIZE-1)
  1549.  
  1550. typedef struct _HASH {
  1551.     struct _HASH *next;     /* next hash   */
  1552.     ubyte code;         /* keycode       */
  1553.     ubyte mask;         /* qual. mask  */
  1554.     ubyte qual;         /* qual. comp  */
  1555.     ubyte stat;         /* string static? */
  1556.     char *str;            /* command string */
  1557. } HASH;
  1558.  
  1559. HASH *Hash[HASHSIZE];
  1560.  
  1561. struct Device *ConsoleDevice;
  1562.  
  1563. ubyte    ctoa[128];
  1564. ubyte    cstoa[128];
  1565.  
  1566. void
  1567. keyctl(im, code, qual)
  1568. IMESS *im;
  1569. register USHORT qual;
  1570. {
  1571.     ubyte buf[256];
  1572.     ubyte c2;
  1573.     short blen = 0;
  1574.  
  1575.     code &= 0xFF;
  1576.     if (im) {
  1577.     im->Qualifier &= ~IEQUALIFIER_REPEAT;
  1578.     blen = DeadKeyConvert(im, buf+1, 254, NULL);
  1579.     if (blen < 0)
  1580.         return;
  1581.     }
  1582.     c2 = 0;
  1583.     if (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1584.     c2 |= QUAL_SHIFT;
  1585.     if (qual & (IEQUALIFIER_CONTROL))
  1586.     c2 |= QUAL_CTRL;
  1587.     if (qual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
  1588.     c2 |= QUAL_AMIGA;
  1589.     if (qual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  1590.     c2 |= QUAL_ALT;
  1591.     if ((qual & IEQUALIFIER_CAPSLOCK) && blen == 1 && buf[1] >= 'a' && buf[1] <= 'z')
  1592.     c2 |= QUAL_SHIFT;
  1593.     if (qual & IEQUALIFIER_LEFTBUTTON)
  1594.     c2 |= QUAL_LMB;
  1595.     if (qual & IEQUALIFIER_MIDBUTTON)
  1596.     c2 |= QUAL_MMB;
  1597.     if (qual & (IEQUALIFIER_RBUTTON))
  1598.     c2 |= QUAL_RMB;
  1599.  
  1600.     {
  1601.     register HASH *hash;
  1602.     for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) {
  1603.         if (hash->code == code && (c2 & hash->mask) == hash->qual)
  1604.         break;
  1605.     }
  1606.  
  1607.     /*
  1608.      *  Use hash entry only if not in command line mode, or if the
  1609.      *  entry does not correspond to an alpha key.
  1610.      */
  1611.  
  1612.     if (hash) {
  1613.         if (c2 || !Comlinemode || blen > 1 || !ctoa[code]) {
  1614.         strcpy(buf, hash->str);
  1615.         do_command(buf);
  1616.         return;
  1617.         }
  1618.     }
  1619.     }
  1620.  
  1621.     /*
  1622.      *    No hash entry
  1623.      */
  1624.  
  1625.     if (blen == 1) {
  1626.     buf[0] = '\'';
  1627.     buf[2] = 0;
  1628.     } else {
  1629.     buf[0] = '\`';
  1630.     buf[blen+1] = '\'';
  1631.     }
  1632.     if (blen)
  1633.     do_command(buf);
  1634. }
  1635.  
  1636. dealloc_hash()
  1637. {
  1638.     register HASH *hash, *hnext = NULL;
  1639.     register short i;
  1640.  
  1641.     for (i = 0; i < HASHSIZE; ++i) {
  1642.     for (hash = Hash[i]; hash; hash = hnext) {
  1643.         hnext = hash->next;
  1644.         if (!hash->stat)
  1645.         FreeMem(hash->str, strlen(hash->str)+1);
  1646.         FreeMem(hash, sizeof(HASH));
  1647.     }
  1648.     Hash[i] = NULL;
  1649.     }
  1650. }
  1651.  
  1652. resethash()
  1653. {
  1654.     register short i;
  1655.     CIO cio;
  1656.     static struct {
  1657.     char *from, *to;
  1658.     } defmap[] = {
  1659.     "esc",      "esc",
  1660.     "c-esc",    "recall",
  1661.     "return",   "return insline up firstnb down",
  1662.     "enter",    "return",
  1663.     "up",       "up",
  1664.     "down",     "down",
  1665.     "right",    "right",
  1666.     "left",     "left",
  1667.     "bs",       "bs",
  1668.     "del",      "del",
  1669.     "tab",      "tab",
  1670.     "a-up",     "scrollup",
  1671.     "a-down",   "scrolldown",
  1672.     "a-r",      "nextr",
  1673.     "a-u",      "while cl (tlate -32 right)",
  1674.     "a-l",      "while cu (tlate +32 right)",
  1675.     "s-up",     "top",
  1676.     "s-down",   "bottom",
  1677.     "s-right",  "last",
  1678.     "s-left",   "first",
  1679.     "s-tab",    "backtab",
  1680.     "s-del",    "deline",
  1681.     "s- ",      "( )",              /* shift space to space */
  1682.     "c-1",      "goto block",
  1683.     "c-c",      "",                 /* break.. map to a nop */
  1684.     "c-l",      "wleft",
  1685.     "c-r",      "wright",
  1686.     "c-i",      "insertmode on",
  1687.     "c-o",      "insertmode off",
  1688.     "c-j",      "join",
  1689.     "c-s",      "split first down",
  1690.     "c-del",    "remeol",
  1691.     "c-n",      "next",
  1692.     "c-p",      "prev",
  1693.     "c-/",      "escimm (find )",
  1694.     "c-]",      "ref",
  1695.     "c-[",      "ctags",
  1696.     "c-g",      "escimm (goto )",
  1697.     "c-up",     "pageup",
  1698.     "c-down",   "pagedown",
  1699.     "c-q",      "quit",
  1700.     "c-f",      "reformat",
  1701.     "c-w",      "wordwrap toggle",
  1702.     "f1",       "escimm (insfile )",
  1703.     "f2",       "escimm (newfile )",
  1704.     "f3",       "escimm (newwindow newfile )",
  1705.     "f6",       "saveold iconify",
  1706.     "f7",       "escimm (bsave )",
  1707.     "f8",       "saveold escimm (newfile )",
  1708.     "f9",       "saveold",
  1709.     "f10",      "saveold quit",
  1710.     "c-b",      "block",
  1711.     "c-u",      "unblock",
  1712.     "a-d",      "bdelete",
  1713.     "a-c",      "bcopy",
  1714.     "a-m",      "bmove",
  1715.     "a-s",      "bsource",
  1716.     "a-S",      "unblock block block bsource",
  1717.     "L-lmb",    "tomouse",      /*  left button                 */
  1718.     "L-mmo",    "tomouse",      /*  mouse move w/left held down */
  1719.     "R-rmb",    "iconify",      /*  right button                */
  1720.     NULL, NULL
  1721.     };
  1722.  
  1723.     dealloc_hash();
  1724.     OpenDevice("console.device", -1, &cio, 0);
  1725.     ConsoleDevice = cio.io_Device;
  1726.     keyboard_init();
  1727.     for (i = 0; defmap[i].from; ++i) {
  1728.     ubyte code, qual;
  1729.     if (get_codequal(defmap[i].from, &code, &qual))
  1730.         addhash(code, 1, 0xFF, qual, defmap[i].to);
  1731.     }
  1732. }
  1733.  
  1734. returnoveride(n)
  1735. {
  1736.     HASH *hash;
  1737.     static ubyte *str;
  1738.     static int stat;
  1739.  
  1740.     for (hash = Hash[0x44&HASHMASK]; hash; hash = hash->next) {
  1741.     if (hash->code == 0x44 && hash->qual == 0) {
  1742.         if (n) {
  1743.         str = (ubyte *)hash->str;
  1744.         stat= hash->stat;
  1745.         hash->str = "return";
  1746.         hash->stat = 1;
  1747.         } else {
  1748.         if (str == NULL) {
  1749.             remhash(0x44, -1, 0);
  1750.         } else {
  1751.             hash->str = (char *)str;
  1752.             hash->stat= stat;
  1753.         }
  1754.         }
  1755.         return(0);
  1756.     }
  1757.     }
  1758.     if (n) {
  1759.     addhash(0x44, 1, 0xFF, 0, "return");
  1760.     str = NULL;
  1761.     }
  1762. }
  1763.  
  1764.  
  1765. addhash(code, stat, mask, qual, str)
  1766. ubyte code, stat, mask, qual;
  1767. ubyte *str;
  1768. {
  1769.     register HASH **p, *hash;
  1770.  
  1771.     hash = *(p = &Hash[code&HASHMASK]);
  1772.     while (hash) {
  1773.     if (hash->code == code && hash->qual == qual && hash->mask == mask) {
  1774.         if (!hash->stat)
  1775.         FreeMem(hash->str, strlen(hash->str)+1);
  1776.         goto newstr;
  1777.     }
  1778.     hash = *(p = &hash->next);
  1779.     }
  1780.     *p = hash = (HASH *)AllocMem(sizeof(HASH), 0);
  1781.     hash->next = NULL;
  1782. newstr:
  1783.     hash->code = code;
  1784.     hash->stat = stat;
  1785.     hash->mask = mask;
  1786.     hash->qual = qual;
  1787.     hash->str = (char *)str;
  1788.     if (!stat)                  /* if not static */
  1789.     hash->str = (char *)strcpy(AllocMem(strlen(str)+1, 0), str);
  1790. }
  1791.  
  1792.  
  1793. remhash(code, mask, qual)
  1794. ubyte code, mask, qual;
  1795. {
  1796.     register HASH *hash, **p;
  1797.  
  1798.     hash = *(p = &Hash[code&HASHMASK]);
  1799.     while (hash) {
  1800.     if (hash->code == code && hash->qual == qual && hash->mask == mask) {
  1801.         if (!hash->stat)
  1802.         FreeMem(hash->str, strlen(hash->str)+1);
  1803.         *p = hash->next;
  1804.         FreeMem(hash, sizeof(HASH));
  1805.         return(1);
  1806.     }
  1807.     hash = *(p = &hash->next);
  1808.     }
  1809.     return(0);
  1810. }
  1811.  
  1812. char *
  1813. keyspectomacro(str)
  1814. char *str;
  1815. {
  1816.     HASH *hash;
  1817.     ubyte code, qual;
  1818.  
  1819.     if (get_codequal(str, &code, &qual)) {
  1820.     for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) {
  1821.         if (hash->code == code) {
  1822.         if (hash->qual == (qual & hash->mask)) {
  1823.             return(hash->str);
  1824.         }
  1825.         }
  1826.     }
  1827.     }
  1828.     return(NULL);
  1829. }
  1830.  
  1831.  
  1832. do_map()
  1833. {
  1834.     ubyte code, qual;
  1835.  
  1836.     if (get_codequal(av[1], &code, &qual)) {
  1837.     addhash(code, 0, 0xFF, qual, av[2]);
  1838.     } else {
  1839.     title("Unknown Key");
  1840.     }
  1841. }
  1842.  
  1843. do_unmap()        /* key   */
  1844. {
  1845.     ubyte code, qual;
  1846.  
  1847.     if (get_codequal(av[1], &code, &qual)) {
  1848.     remhash(code, -1, qual);
  1849.     } else {
  1850.     title("Unknown Command");
  1851.     }
  1852. }
  1853.  
  1854. do_clearmap()
  1855. {
  1856.     resethash();
  1857. }
  1858.  
  1859. /*
  1860.  * SAVEMAP  file
  1861.  * SAVESMAP file
  1862.  */
  1863.  
  1864. do_savemap()
  1865. {
  1866.     char sysalso;
  1867.     char err = 0;
  1868.     char buf[256];
  1869.     long xfi;
  1870.     register int i;
  1871.     register HASH *hash;
  1872.     register ubyte *ptr;
  1873.  
  1874.     xfi = xfopen(av[1], "w", 512);
  1875.     if (xfi) {
  1876.     sysalso = av[0][4] == 's';
  1877.     for (i = 0; i < HASHSIZE; ++i) {
  1878.         for (hash = Hash[i]; hash; hash = hash->next) {
  1879.         if (hash->stat == 0 || sysalso) {
  1880.             char soc = '(';
  1881.             char eoc = ')';
  1882.             char ksoc = '(';
  1883.             char keoc = ')';
  1884.             short len;
  1885.  
  1886.             for (ptr = (ubyte *)hash->str; *ptr; ++ptr) {
  1887.             if (*ptr == '(')
  1888.                 break;
  1889.             if (*ptr == '\`') {
  1890.                 soc = '\`';
  1891.                 eoc = '\'';
  1892.                 break;
  1893.             }
  1894.             }
  1895.             len = strlen(ptr = cqtoa(hash->code, hash->qual)) - 1;
  1896.             if (ptr[len] == '(' || ptr[len] == ')') {
  1897.             ksoc = '\`';
  1898.             keoc = '\'';
  1899.             }
  1900.             sprintf(buf, "map %c%s%c %c%s%c\n", ksoc, cqtoa(hash->code, hash->qual), keoc, soc, hash->str, eoc);
  1901.             xfwrite(xfi, buf, strlen(buf));
  1902.         }
  1903.         }
  1904.     }
  1905.     xfclose(xfi);
  1906.     if (err)
  1907.         title ("Unable to Write");
  1908.     else
  1909.         title ("OK");
  1910.     } else {
  1911.     title("Unable to open file");
  1912.     }
  1913. }
  1914.  
  1915. /*
  1916.  *  Nitty Gritty.
  1917.  *
  1918.  *  keyboard_init:  initialize for get_codequal() and cqtoa()
  1919.  *  get_codequal:   convert a qualifier-string combo to a keycode and qual.
  1920.  *  cqtoa:        convert a keycode and qual to a qual & string
  1921.  */
  1922.  
  1923. #define LN(a,b,c,d)  ((a<<24)|(b<<16)|(c<<8)|d)
  1924.  
  1925. long lname[] = {
  1926.     LN('e','s','c', 0  ), LN('f','1', 0 , 0  ), LN('f','2', 0 , 0  ),
  1927.     LN('f','3', 0 , 0  ), LN('f','4', 0 , 0  ), LN('f','5', 0 , 0  ),
  1928.     LN('f','6', 0 , 0  ), LN('f','7', 0 , 0  ), LN('f','8', 0 , 0  ),
  1929.     LN('f','9', 0 , 0  ), LN('f','1','0', 0  ), LN('d','e','l', 0  ),
  1930.     LN('b','a','c', 0  ), LN('b','s', 0 , 0  ), LN('t','a','b', 0  ),
  1931.     LN('h','e','l', 0  ), LN('r','e','t', 0  ), LN('u','p', 0 , 0  ),
  1932.     LN('d','o','w', 0  ), LN('r','i','g', 0  ), LN('l','e','f', 0  ),
  1933.     LN('e','n','t', 0  ), LN('n','k','-', 0  ), LN('n','k','.', 0  ),
  1934.     LN('n','k','0', 0  ),   /* 24 */
  1935.     LN('n','k','1', 0  ), LN('n','k','2', 0  ), LN('n','k','3', 0  ),
  1936.     LN('n','k','4', 0  ), LN('n','k','5', 0  ), LN('n','k','6', 0  ),
  1937.     LN('n','k','7', 0  ), LN('n','k','8', 0  ), LN('n','k','9', 0  ),
  1938.     LN('n','k','(', 0  ), LN('n','k',')', 0  ), LN('n','k','/', 0  ), /*34-36*/
  1939.     LN('n','k','*', 0  ), LN('n','k','+', 0  ),
  1940.     LN('l','m','b',0xE8), LN('m','m','b',0xEA), LN('r','m','b',0xE9),
  1941.     LN('m','m','o',QMOVE),
  1942.     0
  1943. };
  1944.  
  1945.  
  1946. /*
  1947.  *  ESC:    x1B
  1948.  *  FUNCKEYS:    x9B 30 7E to x9B 39 7E
  1949.  *  DEL:    x7E
  1950.  *  BS:     x08
  1951.  *  TAB:    x09
  1952.  *  RETURN:    x0D
  1953.  *  HELP    x9B 3F 7E
  1954.  *  UP/D/L/R    x9B 41/42/44/43
  1955.  *  NK0-9,-,.,ENTER
  1956.  *
  1957.  *  Mouse buttons
  1958.  */
  1959.  
  1960. keyboard_init()
  1961. {
  1962.     static struct InputEvent ievent = { NULL, IECLASS_RAWKEY };
  1963.     ubyte buf[32];
  1964.     register short i, q, len;
  1965.  
  1966.     lname[16] |= 0x44;
  1967.     lname[21] |= 0x43;
  1968.  
  1969.     for (i = 0; i < 128; ++i) {
  1970.     ievent.ie_Code = i;
  1971.     ievent.ie_Qualifier = 0;
  1972.     ievent.ie_position.ie_addr = NULL;
  1973.     len = RawKeyConvert(&ievent,buf,32,NULL);
  1974.     switch(len) {
  1975.     case 1:     /*    ESC/DEL/BS/TAB/NKx  */
  1976.         if (buf[0] >= 32 && buf[0] < 127)
  1977.         ctoa[i] = buf[0];
  1978.         switch(buf[0]) {
  1979.         case 0x1B:    lname[ 0] |= i; break;
  1980.         case 0x7F:    lname[11] |= i; break;
  1981.         case 0x09:    lname[14] |= i; break;
  1982.         case 0x08:    lname[12] |= i; lname[13] |= i; break;
  1983.         case '(': if (i > 0x3A) lname[34] |= i; break;
  1984.         case ')': if (i > 0x3A) lname[35] |= i; break;
  1985.         case '/': if (i > 0x3A) lname[36] |= i; break;
  1986.         case '*': if (i > 0x3A) lname[37] |= i; break;
  1987.         case '-': if (i > 0x3A) lname[22] |= i; break;
  1988.         case '+': if (i > 0x3A) lname[38] |= i; break;
  1989.         case '.': if (i > 0x3A) lname[23] |= i; break;
  1990.         default:
  1991.         if (i >= 0x0F && buf[0] >= '0' && buf[0] <= '9')
  1992.             lname[24+buf[0]-'0'] |= i;
  1993.         }
  1994.         break;
  1995.     case 2:     /*    cursor            */
  1996.         if (buf[0] == 0x9B) {
  1997.         switch(buf[1]) {
  1998.         case 0x41:  lname[17] |= i;  break;
  1999.         case 0x42:  lname[18] |= i;  break;
  2000.         case 0x43:  lname[19] |= i;  break;
  2001.         case 0x44:  lname[20] |= i;  break;
  2002.         }
  2003.         }
  2004.         break;
  2005.     case 3:     /*    function/help        */
  2006.         if (buf[0] == 0x9B && buf[2] == 0x7E) {
  2007.         if (buf[1] == 0x3F)
  2008.             lname[15] |= i;
  2009.         if (buf[1] >= 0x30 && buf[1] <= 0x39)
  2010.             lname[buf[1]-0x30+1] |= i;
  2011.         }
  2012.         break;
  2013.     }
  2014.     }
  2015.     for (i = 0; i < 128; ++i) {
  2016.     ievent.ie_Code = i;
  2017.     ievent.ie_Qualifier = IEQUALIFIER_LSHIFT;
  2018.     ievent.ie_position.ie_addr = NULL;
  2019.     len = RawKeyConvert(&ievent,buf,32,NULL);
  2020.     if (len == 1)
  2021.         cstoa[i] = buf[0];
  2022.     }
  2023.     {
  2024.     ubyte code, qual;
  2025.     get_codequal("c", &code, &qual);
  2026.     CtlC = code;
  2027.     }
  2028. }
  2029.  
  2030.  
  2031. ubyte *
  2032. cqtoa(code, qual)
  2033. register int qual;
  2034. {
  2035.     static ubyte buf[32];
  2036.     register ubyte *ptr = buf;
  2037.     register int i;
  2038.  
  2039.     if (qual & QUAL_SHIFT)
  2040.     *ptr++ = 's';
  2041.     if (qual & QUAL_CTRL)
  2042.     *ptr++ = 'c';
  2043.     if (qual & QUAL_ALT)
  2044.     *ptr++ = 'a';
  2045.     if (qual & QUAL_AMIGA)
  2046.     *ptr++ = 'A';
  2047.     if (qual & QUAL_LMB)
  2048.     *ptr++ = 'L';
  2049.     if (qual & QUAL_MMB)
  2050.     *ptr++ = 'M';
  2051.     if (qual & QUAL_RMB)
  2052.     *ptr++ = 'R';
  2053.     if (qual)
  2054.     *ptr++ = '-';
  2055.     for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) {
  2056.     if ((lname[i]&0xFF) == code) {
  2057.         *ptr++ = (lname[i]>>24);
  2058.         *ptr++ = (lname[i]>>16);
  2059.         *ptr++ = (lname[i]>>8);
  2060.         break;
  2061.     }
  2062.     }
  2063.     if (i == sizeof(lname)/sizeof(lname[0]))
  2064.     *ptr++ = ctoa[code];
  2065.     *ptr++ = 0;
  2066.     return(buf);
  2067. }
  2068.  
  2069.  
  2070. get_codequal(str, pcode, pqual)
  2071. ubyte *pcode, *pqual;
  2072. register ubyte *str;
  2073. {
  2074.     register ubyte qual;
  2075.     register short i;
  2076.  
  2077.     qual = 0;
  2078.     if (strlen(str) > 1) {
  2079.     for (; *str && *str != '-'; ++str) {
  2080.         if (*str == 's')
  2081.         qual |= QUAL_SHIFT;
  2082.         if (*str == 'c')
  2083.         qual |= QUAL_CTRL;
  2084.         if (*str == 'a')
  2085.         qual |= QUAL_ALT;
  2086.         if (*str == 'A')
  2087.         qual |= QUAL_AMIGA;
  2088.         if (*str == 'L')
  2089.         qual |= QUAL_LMB;
  2090.         if (*str == 'M')
  2091.         qual |= QUAL_MMB;
  2092.         if (*str == 'R')
  2093.         qual |= QUAL_RMB;
  2094.         if (!qual)
  2095.         goto notqual;
  2096.     }
  2097.     if (*str)
  2098.         ++str;
  2099.     }
  2100. notqual:
  2101.     if (strlen(str) != 1) {           /* long name   */
  2102.     register short shift = 24;
  2103.     register long mult = 0;
  2104.  
  2105.     *pqual = qual;
  2106.     while (*str && shift >= 8) {
  2107.         if (*str >= 'A' && *str <= 'Z')
  2108.         *str = *str - 'A' + 'a';
  2109.         mult |= *str << shift;
  2110.         shift -= 8;
  2111.         ++str;
  2112.     }
  2113.     for (i = 0; lname[i]; ++i) {
  2114.         if (mult == (lname[i] & 0xFFFFFF00)) {
  2115.         *pcode = lname[i] & 0xFF;
  2116.         return(1);
  2117.         }
  2118.     }
  2119.     } else {            /*    single character keycap */
  2120.     for (i = 0; i < sizeof(ctoa); ++i) {
  2121.         if (*str == ctoa[i]) {
  2122.         *pcode = i;
  2123.         *pqual = qual;
  2124.         return(1);
  2125.         }
  2126.     }
  2127.     for (i = 0; i < sizeof(cstoa); ++i) {
  2128.         if (*str == cstoa[i]) {
  2129.         *pcode = i;
  2130.         *pqual = qual|QUAL_SHIFT;
  2131.         return(1);
  2132.         }
  2133.     }
  2134.     }
  2135.     return(0);
  2136. }
  2137.  
  2138. \Rogue\Monster\
  2139. else
  2140.   echo "will not over write ./src/keyboard.c"
  2141. fi
  2142. if [ `wc -c ./src/keyboard.c | awk '{printf $1}'` -ne 14051 ]
  2143. then
  2144. echo `wc -c ./src/keyboard.c | awk '{print "Got " $1 ", Expected " 14051}'`
  2145. fi
  2146. echo "Finished archive 4 of 6"
  2147. # if you want to concatenate archives, remove anything after this line
  2148. exit
  2149. -- 
  2150. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2151. Have five nice days.
  2152.